use std::collections::HashMap;
use std::sync::{Arc, Mutex, RwLock};

lazy_static::lazy_static! {
    pub(crate) static ref STATE_MACHINE_MANAGER: RwLock<WorkflowStateMachineManager> = RwLock::new(WorkflowStateMachineManager::new());
}

use model_graph_types::container::workflow::WorkflowResult;
use model_graph_types::modeling::Value;

use super::state_machine::{WorkflowStateMachine, WorkflowStateMachineState};
#[derive(Debug)]
pub struct WorkflowStateMachineManager {
    machines: HashMap<String, Arc<Mutex<WorkflowStateMachine>>>,
}

impl WorkflowStateMachineManager {
    fn new() -> Self {
        Self {
            machines: HashMap::new(),
        }
    }
}

impl WorkflowStateMachineManager {
    /// 通过ID获取
    pub fn get_machine(&self, key: &String) -> anyhow::Result<Arc<Mutex<WorkflowStateMachine>>> {
        if let Some(machine) = self.machines.get(key) {
            Ok(machine.clone())
        } else {
            Err(anyhow::anyhow!(
                "没有找到该状态机:{} {:?}",
                key,
                self.machines.keys()
            ))
        }
    }
    /// 插入
    pub fn insert_machine(
        &mut self,
        key: String,
        arc_machine: Arc<Mutex<WorkflowStateMachine>>,
    ) -> anyhow::Result<()> {
        if self.machines.contains_key(&key) {
            return Err(anyhow::anyhow!("已经存在"));
        } else {
            self.machines.insert(key, arc_machine);
        }
        Ok(())
    }
    /// 插入
    pub fn remove_machine(&mut self, key: &String) -> anyhow::Result<()> {
        if self.machines.contains_key(key) {
            self.machines.remove(key);
        }
        Ok(())
    }
    /// 插入
    pub fn push_node_result(
        &mut self,
        key: &String,
        node_id: &String,
        result: HashMap<String, Value>,
    ) -> anyhow::Result<()> {
        if let Some(machine) = self.machines.get(key) {
            
        }
        Ok(())
    }
}

pub fn get_machine(key: &String) -> anyhow::Result<Arc<Mutex<WorkflowStateMachine>>> {
    STATE_MACHINE_MANAGER
        .read()
        .map_err(|err| anyhow::anyhow!("获取锁失败:{}", err))?
        .get_machine(key)
}

pub fn insert_machine(
    key: String,
    arc_machine: Arc<Mutex<WorkflowStateMachine>>,
) -> anyhow::Result<()> {
    STATE_MACHINE_MANAGER
        .write()
        .map_err(|err| anyhow::anyhow!("获取锁失败:{}", err))?
        .insert_machine(key, arc_machine)
}

pub fn remove_machine(key: &String) -> anyhow::Result<()> {
    STATE_MACHINE_MANAGER
        .write()
        .map_err(|err| anyhow::anyhow!("获取锁失败:{}", err))?
        .remove_machine(key)
}

pub fn put_machine_result(key: &String, result: WorkflowResult) -> anyhow::Result<()> {
    let m = STATE_MACHINE_MANAGER
        .read()
        .map_err(|err| anyhow::anyhow!("获取锁失败:{}", err))?
        .get_machine(key)?;

    let mut machine = m
        .lock()
        .map_err(|err| anyhow::anyhow!("获取锁失败:{}", err))?;
    machine.result = Some(result);
    machine.set_state(WorkflowStateMachineState::Completed);
    Ok(())
}

pub fn get_machine_result(key: &String) -> anyhow::Result<Option<WorkflowResult>> {
    let m = STATE_MACHINE_MANAGER
        .read()
        .map_err(|err| anyhow::anyhow!("获取锁失败:{}", err))?
        .get_machine(key)?;
    let result = m
        .lock()
        .map_err(|err| anyhow::anyhow!("获取锁失败:{}", err))?
        .result
        .clone();
    Ok(result)
}
